#include <INTRINS.H>
#include <myIAP.h>

uint8_t code *POINT = 0x0000; // code指指针指向代码区而非数据区

/**
 * @brief EEPROM的擦除
 *
 */
void IAP_EEPROM_erase(uint16_t IAP_Address)
{
    EA = 0;                               // 关闭总中断
    IAPADE = IAP_EEPROM;                  // 地址选定:EEPROM
    IAPADH = (uint8_t)(IAP_Address >> 8); // 高地址输入
    IAPADL = (uint8_t)IAP_Address;        // 低地址输入
    IAPKEY = 0xF0;                        // 断掉IAP保护240个时间
    IAPCTL = 0x20;                        // 擦除预指令 0010 0000 b
    IAPCTL |= 0x02;                       // 执行擦除指令 xxxx xx1x b
    _nop_();                              // 等待至少8个nop
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    EA = 1; // 开启总中断
    IAPADE = IAP_APROM;
}

/**
 * @brief EEPROM写数据
 * (在写之前记得擦除)
 * @param IAP_Address
 * @param IAP_Data
 */
void IAP_EEPROM_write(uint16_t IAP_Address, uint8_t IAP_Data)
{
    EA = 0;                               // 关闭总中断
    IAPADE = IAP_EEPROM;                  // 地址选定:EEPROM
    IAPDAT = IAP_Data;                    // 送数据到IAP数据寄存器
    IAPADH = (uint8_t)(IAP_Address >> 8); // 高地址输入
    IAPADL = (uint8_t)IAP_Address;        // 低地址输入
    IAPKEY = 0xF0;                        // 断掉IAP保护240个时间
    IAPCTL = 0x10;                        // 预写入 0001 0000 b
    IAPCTL |= 0x02;                       // 执行写入 xxxx xx1x b
    _nop_();                              // 等待至少8个nop
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    EA = 1; // 开启总中断
    IAPADE = IAP_APROM;
}

/**
 * @brief EEPROM读数据
 *
 * @param IAP_Address 从地址位读
 * @return uint8_t 读到的数据
 */
uint8_t IAP_EEPROM_read(uint16_t IAP_Address)
{
    uint8_t IAP_Data = 0;
    EA = 0;
    IAPADE = IAP_EEPROM;
    IAP_Data = *(POINT + IAP_Address);
    EA = 1;
    IAPADE = IAP_APROM;
    return IAP_Data;
}
